<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>2_react生命周期（旧）</title>
</head>
<body>
  <div id="test"></div>
  
  <script src="../js/react.development.js"></script>
  <script src="../js/react-dom.development.js"></script>
  <!-- Don't use this in production: -->
  <script src="../js/babel.min.js"></script>
  <!-- 引入prop-types.js  用于对组件标签属性进行限制 -->

  <script type="text/babel">
    /* 
    1.初始化阶段：由ReactDOM.render()触发---初次渲染
        constructor()
        componentWillMount()
        render()
        componentDidMount()   ====> 常用
            一般在这个钩子中做一些初始化的事，例如：开启定时器、发送网络请求、订阅消息

    2.更新阶段：由组件内部this.setState()或父组件重新render触发
        shouldComponentUpdate()
        componentWillUpdate()
        render()   ====> 必须使用的一个
        componentDidUpdate()

    3.卸载组件：由ReactDOM.unmountComponentAtNode()触发
        componentWillUnmount()   ====> 常用
            一般在这个钩子中做一些收尾的事，例如：关闭定时器、取消订阅消息
    */

    // 创建组件
    class Count extends React.Component {
      // 构造器
      constructor(props) {
        console.log("Count---constructor");
        super(props)
        
        // 初始化状态
        this.state = {
          count: 0
        }
      }

      /* state = {
        count: 0
      } */

      // 加1按钮的回调
      add = () => {
        let {count} = this.state
        
        this.setState({
          count: count+1
        })
      }

      // 卸载组件按钮的回调
      death = () => {
        ReactDOM.unmountComponentAtNode(document.getElementById("test"))
      }

      // 强制更新按钮的回调
      force = () => {
        this.forceUpdate()
      }

      // 组件将要挂载的钩子
      componentWillMount() {
        console.log("Count---componentWillMount")
      }

      // 新版React的可能被遗弃的生命周期 用于替换componentWillMount
      /* UNSAFE_componentWillMount() {
        console.log("Count---UNSAFE_componentWillMount")
      } */


      // 组件挂载完毕的钩子
      componentDidMount() {
        console.log("Count---componentDidMount")
      }

      // 组件将要卸载的钩子
      componentWillUnmount() {
        console.log("Count---componentWillUnmount")
      }

      // 控制组件更新的阀门
      /* 
        不写的话 底层会补
        写了就要返回布尔值
      */
      shouldComponentUpdate() {
        console.log("Count---shouldComponentUpdate")
        // turned undefined instead of a boolean value. Make sure to return true or false.
        return true
        // return false
      }

      // 组件将要更新的钩子
      componentWillUpdate() {
        console.log("Count---componentWillUpdate")
      }

      // 新版React的可能被遗弃的生命周期 用于替换componentWillUpdate
      /* UNSAFE_componentWillUpdate() {
        console.log("Count---UNSAFE_componentWillUpdate")
      } */

      // 组件更新完毕后的钩子
      componentDidUpdate() {
        console.log("Count---componentDidUpdate")
      }

      render() {
        console.log("Count---render")
        const {count} = this.state

        return (
          <div>
            <h2>当前求和为{count}</h2>
            <button onClick={this.add}>点我+1</button>
            <button onClick={this.death}>点我消失</button>
            <button onClick={this.force}>不更改任何状态中的数据，强制更新一下</button>
          </div>
        )
      }
    }

    class A extends React.Component {
      // 初始化状态
      state = { carName: "奔驰" }

      changCar = () => {
        this.setState({
          carName: '奥拓'
        })
      }

      render() {
        return (
          <div>
            <div>我是A组件</div>
            <button onClick={this.changCar}>换车</button>
            <B carName={this.state.carName} />
          </div>
        )
      }
    }

    class B extends React.Component {
      // 组件将要接收新的props的钩子
      componentWillReceiveProps(props) {
        // componentWillReceiveNewProps
        /* 
          第一次不生效，第二次生效
        */

        console.log("B---componentWillReceiveProps", props)
      }

      // 新版React的可能被遗弃的生命周期 用于替换componentWillReceiveProps
      /* UNSAFE_componentWillReceiveProps(props) {
        console.log("B---UNSAFE_componentWillReceiveProps", props)
      } */

      // 控制组件更新的阀门
      shouldComponentUpdate() {
        console.log("B---shouldComponentUpdate")
        return true
      }

      // 组件将要更新的钩子
      componentWillUpdate() {
        console.log("B---componentWillUpdate")
      }

      // 组件更新完毕后的钩子
      componentDidUpdate() {
        console.log("B---componentDidUpdate")
      }

      render() {
        console.log("B---render")
        return (
          <div>
            我是B组件，接收到的车是：{this.props.carName}  
          </div>
        )
      }
    }

    // 渲染组件
    ReactDOM.render(<Count/>, document.getElementById("test"))
  </script>
</body>
</html>